﻿package fr.babos.core.mvc
{
	import com.zouloux.core.data.remote.IRemote;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import fr.babos.core.data.collect.DataCollection;
	import fr.babos.core.data.collect.IDataCollection;
	import fr.babos.core.data.remote.IDataRemote;
	import fr.babos.core.events.DataEvent;
	import fr.babos.core.events.DynamicErrorEvent;
	import fr.babos.core.mvc.IModel;
	import fr.babos.core.roles.IDisposable;
	import fr.babos.core.roles.IEnablable;
	import fr.babos.core.roles.IErrorDispatcher;
	import fr.babos.core.roles.IInitializable;
	
	/**
	 * Le modèle de données de base.
	 * @author ZoulouX
	 */
	public class Model extends EventDispatcher implements IModel, IEventDispatcher, IInitializable, IDisposable, IEnablable, IErrorDispatcher
	{
		/**
		 * L'état du model
		 */
		protected var _ready					:Boolean 							= false;
		
		/**
		 * La collection principale
		 */
		protected var _collection				:IDataCollection					= new DataCollection();
		
		/**
		 * La remote
		 */
		protected var _remote					:IDataRemote;
		
		/**
		 * Si le model est activé ou non
		 */
		protected var _enabled					:Boolean							= false;
		
		
		/**
		 * L'état du model
		 */
		public function get ready ():Boolean { return _ready; }
		protected function set ready (value:Boolean):void 
		{
			// S'il y a un changement d'état
			if (value != _ready)
			{
				// Enregistrer l'état
				_ready = value;
				
				// Dispatcher si c'est prêt
				if (_ready)
					dispatchReady();
			}
		}
		
		/**
		 * Récupérer la collection associée au model
		 */
		public function get collection ():IDataCollection { return _collection; }
		protected function set collection (value:IDataCollection):void 
		{
			// Vérifier que la référence ne soit pas nulle
			if (value != null)
				_collection = value;
			else
				throw new Error("Model.collection Error. Can't associate null collection.");
		}
		
		/**
		 * La remote associée
		 */
		public function get remote ():IRemote { return _remote; }
		protected function set remote (value:IRemote):void 
		{
			// Vérifier que la référence ne soit pas nulle
			if (value != null)
				_remote = value;
			else
				throw new Error("Model.remote Error. Can't associate null remote.");
		}
		
		/**
		 * Récupérer l'état d'activation du model
		 */
		public function get enabled ():Boolean { return _enabled }
		public function set enabled (value:Boolean):void
		{
			// Vérifier que la valeur soit différente
			if (value != _enabled)
			{
				// Enregistrer la nouvelle valeur
				_enabled = value;
				
				// Dispatcher l'event
				if (value)
					dispatchEvent(new Event(Event.ACTIVATE));
				else
					dispatchEvent(new Event(Event.DEACTIVATE));
			}
		}
		
		/**
		 * Le constructeur
		 */
		public function Model ()
		{
			
		}
		
		/**
		 * Initialisation du model.
		 * Méthode abstraite à overrider.
		 */
		public function init ():void
		{
			
		}
		
		/**
		 * Le model est prêt
		 */
		public function dispatchReady ():void
		{
			dispatchEvent(new DataEvent(DataEvent.READY));
		}
		
		/**
		 * Déclancher une erreur
		 * @param	pMessage : Le message d'erreur personnalisé
		 * @param	pCode : Le code de l'erreur
		 */
		public function dispatchError (pMessage:String, pCode:uint):void
		{
			dispatchEvent(new DynamicErrorEvent(DynamicErrorEvent.DATA_ERROR, pMessage, pCode));
		}
		
		/**
		 * Effacer cet élément.
		 * Méthode abstraite à overrider.
		 */
		public function dispose ():void
		{
			
		}
	}
}